# 用streamlit写一个简单的web应用，实现以下功能：
# 1. 上传一个excel文件
# 2. 解析excel文件，将数据显示在页面上
import streamlit as st
import pandas as pd  
from st_aggrid import AgGrid

from model.person import Person


st.title('Excel文件解析')

uploaded_file = st.file_uploader("拖拽xlsx文件到下面对话框中或点击Browse files按钮上传文件", type=["xlsx", "xls"])


df = None  # 用于存储解析后的数据 


if uploaded_file is not None:
    # 读取Excel文件，并将数据存储到DataFrame中，index从1开始
    df = pd.read_excel(uploaded_file)  
    df.index = range(1, len(df) + 1)  

    # 构造一个空的DataFrame，用于存储验证成功的Person对象，列名与原DataFrame相同，增加2列，分别是验证结果和错误信息
    df_result = pd.DataFrame(columns=df.columns)  
    df_result.insert(0, '验证结果', '')  
    df_result.insert(1, '错误信息', '')  


    # 遍历每一行数据，并进行验证，最后弹出一个通知框，显示验证结果
    success_rows = []  # 成功验证的行数
    failed_rows = []  # 验证失败的行数 
    progress_bar = st.progress(0,text='正在加载和处理数据...')  # 进度条 


    with st.spinner('正在验证数据...'):  # 显示一个加载中的提示框


        for index, row in df.iterrows():
            df_result.loc[index] = row.to_dict()  
            try:
                # 尝试将数据转换为Person模型
                person = Person(**row.to_dict())  
                person.send_to_api('http://localhost:8000/api/persons') 
                df_result.loc[index, '验证结果'] = '成功'    
                success_rows.append(index) # 验证成功，则计数器加1
            except Exception as e:
                df_result.loc[index, '验证结果'] = '失败'  
                df_result.loc[index, '错误信息'] = str(e)  
                # 验证失败，则弹出一个通知框，显示错误信息,显示后自动消失 
                failed_rows.append(index) # 验证失败，则计数器加1
            finally:
                progress_bar.progress(index / len(df),text='正在加载和处理数据...')  # 更新进度条


        col1,col2 = st.columns(2)
            # 显示成功的行数
        if success_rows:
            with col1:
                st.success(f"成功 {len(success_rows)} 行: {', '.join(map(str, success_rows))}")  
                # 显示验证成功的Person对象
                AgGrid(df_result[df_result.index.isin(success_rows)]) # 显示验证结果 

            # 显示验证失败的行数
        if failed_rows:
            with col2:
                st.error(f"失败 {len(failed_rows)} 行: {', '.join(map(str, failed_rows))}") 
                # 显示验证成功的Person对象
                AgGrid(df_result[df_result.index.isin(failed_rows)]) # 显示验证结果
        
        st.info('在表格数据上点击右键，选择"导出为Excel"，即可下载结果')
